﻿using System;

namespace Birkelund.QueryStrings
{
    /// <summary>
    /// Arguments for token parser failure
    /// </summary>
    [Serializable]
    public class FailureArgs : EventArgs
    {
        /// <summary>
        /// The name key of the key which caused the failure
        /// </summary>
        public string KeyName { get; private set; }

        /// <summary>
        /// The read value which caused the failure
        /// </summary>
        public string Value { get; private set; }

        /// <summary>
        /// The entire uri of failed request
        /// </summary>
        public Uri FullUri { get; private set; }

        /// <summary>
        /// The reason for the error to occur
        /// </summary>
        public FailureReason Reason { get; private set; }

        /// <summary>
        /// The type which the parsed expects
        /// </summary>
        public Type ExpectedType { get; set; }

        /// <summary>
        /// The Exception which caused the failure. Is null as long as no exception has occured
        /// </summary>
        public Exception Exception { get; private set; }


        /// <summary>
        /// Initializes a new instance of the <see cref="FailureArgs"/> class.
        /// </summary>
        /// <param name="keyName">The key.</param>
        /// <param name="value">The value.</param>
        /// <param name="fullUri">The full URL.</param>
        /// <param name="cause">The cause.</param>
        /// <param name="expectedType">The type of the token</param>
        public FailureArgs(string keyName, string value, Uri fullUri, FailureReason cause, Type expectedType)
            : this(keyName, value, fullUri, cause, expectedType, null)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FailureArgs"/> class.
        /// </summary>
        /// <param name="keyName">The keyName.</param>
        /// <param name="value">The value.</param>
        /// <param name="fullUri">The full URI.</param>
        /// <param name="cause">The cause.</param>
        /// <param name="expectedType">The type of the token</param>
        /// <param name="exception">The exception.</param>
        public FailureArgs(string keyName, string value, Uri fullUri, FailureReason cause, Type expectedType, Exception exception)
        {
            KeyName = keyName;
            Value = value;
            FullUri = fullUri;
            Reason = cause;
            Exception = exception;
            ExpectedType = expectedType;
        }

        /// <summary>
        /// Returns a string representation of this object
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            string message = string.Format("KeyName='{0}', Value='{1}', Reason='{2}', FullUri='{3}',",
                NullIfNull(KeyName), NullIfNull(Value), Reason, NullIfNull(FullUri));

            if (ExpectedType != null)
            {
                message += ", ExpectedType='" + ExpectedType.FullName+ "'";
            }
            if (Exception != null)
            {
                message += ", Exception='" + Exception.Message + "'";
            }

            return message;
        }

        private static string NullIfNull(object input)
        {
            return input == null ? "null" : input.ToString();
        }
    }
}